package com.example.demo.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.UsersInfo;
import com.example.demo.entity.dto.UserLoginDTO2;
import com.example.demo.entity.vo.RegisterByPhoneVO2;
import com.example.demo.entity.vo.UserLoginByPassVO;
import com.example.demo.result.MyPage;
import com.example.demo.result.Result;
import com.example.demo.service.IUsersInfoService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

/**
 * <p>
 * 用户信息 前端控制器
 * </p>
 *
 * @author Mr.Abel
 * @since 2024-03-13
 */
@Slf4j
@Api(tags = "用户信息2.0")
@RestController
@RequestMapping("/users-info")
public class UsersInfoController {

    @Resource
    private IUsersInfoService usersInfoService;

    @Autowired
    private RedisTemplate redisTemplate;

    //缓存是不允许在controller层操作的
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "查询个人信息")
    @SaCheckLogin
    @GetMapping("/getUserInfoV2")
    public Result getUserInfoV2(){
        //1、通过token获取id
        Integer id = StpUtil.getLoginIdAsInt();
        UsersInfo usersInfo = usersInfoService.selectById(id);
        return Result.success(usersInfo);
    }


    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "查询个人信息(过时)，请使用getUserInfoV2")
    @SaCheckLogin
    @GetMapping("/getUserInfo")
    public Result getUserInfo(){
        //1、通过token获取id
        Integer id = StpUtil.getLoginIdAsInt();
        //2、得有一个key
        String key = "userinfo:"+id;
        //3、 key是否已经存在
        //4、 首先查询redis
        if(redisTemplate.hasKey(key)){
            log.info("查询缓存逻辑");
            //5、直接查询redis
            return Result.success(redisTemplate.opsForValue().get(key));
        }
        log.info("通过数据库查询");
        //6、通过id查询用户信息
        UsersInfo usersInfo = usersInfoService.getById(id);
        //7、给redis一份
        redisTemplate.opsForValue().set(key,usersInfo);
        //8、返回
        return Result.success(usersInfo).msg("查询成功");
    }




    /**
     * 根据手机号模糊查询用户
     * @param phone
     * @return
     */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "根据手机号模糊查询用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone",value = "电话号码",required = true)
    })
    //只有登录之后才能访问到
    @SaCheckLogin
    @GetMapping("/selectByPhone/{phone}")
    public Result<List<UserLoginDTO2>> getByPhone(@PathVariable String phone) {
        List<UserLoginDTO2> byPhone = usersInfoService.findByPhone(phone);
        return Result.success(byPhone).msg("查询成功");
    }

    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "用户退出登录")
    //只有登录之后才能访问到
    @SaCheckLogin
    @PostMapping("/loginOut")
    public Result loginOut(){
        // 当前会话注销登录
        StpUtil.logout();
        return Result.success().msg("注销成功");
    }


    /**
     * 查询所有接口
     * @return
     */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "查询用户信息所有数据")
    @GetMapping
    public Result<List<UsersInfo>> findAll() {
        return Result.success(usersInfoService.list()).msg("查询成功");
    }

    /**
     * 根据id查询数据接口
     * @param id
     * @return
     */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "根据id查询数据接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "组件id",required = true)
    })
    @GetMapping("/{id}")
    public Result<UsersInfo> findOne(@PathVariable Integer id) {
        return Result.success(usersInfoService.getById(id)).msg("查询成功");
    }

    /**
     * 分页查询接口
     * @param pageNum
     * @param pageSize
     * @return
     */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "分页查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum",value = "页码",example="1",required = true),
            @ApiImplicitParam(name = "pageSize",value = "每页多少条",example="10",required = true)
    })
    @GetMapping("/page")
    public Result<MyPage<UsersInfo>> findPage(@RequestParam Integer pageNum,@RequestParam Integer pageSize) {
        QueryWrapper<UsersInfo> queryWrapper = new QueryWrapper<>();
        return Result.success().data(usersInfoService.page(new Page<>(pageNum, pageSize), queryWrapper)).msg("查询成功");
    }

    /**
    * 新增
    * @param
    * @return
    */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "注册账号2.0")
    @PostMapping("/add")
    public Result<String> add(@Valid @RequestBody RegisterByPhoneVO2 registerByPhoneVO2) {
        UsersInfo usersInfo = new UsersInfo();
        BeanUtil.copyProperties(registerByPhoneVO2, usersInfo);
        usersInfoService.register(usersInfo);
        return Result.success().msg("注册成功");
    }

    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "登录2.0")
    @PostMapping("/login")
    public Result<UserLoginDTO2> login(@Valid @RequestBody UserLoginByPassVO userLoginByPassVO) {
        UsersInfo usersInfo = new UsersInfo();
        BeanUtil.copyProperties(userLoginByPassVO, usersInfo);
        UserLoginDTO2 login = usersInfoService.login(usersInfo);

        //保存登录信息
        StpUtil.login(login.getUserId());
        //获取当前会话的token
        String tokenValue = StpUtil.getTokenValue();
        //设置token
        login.setToken(tokenValue);

        return Result.success(login).msg("登录成功");
    }


    /**
     * 更新接口
     * @param
     * @return
     */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "更新接口")
    @PutMapping
    public Result<String> save(@RequestBody UsersInfo usersInfo) {
        usersInfoService.saveOrUpdate(usersInfo);
        return Result.success().msg("更新成功");
    }

    /**
     * 删除接口
     * @param id
     * @return
     */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "删除接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "组件id",required = true)
    })
    @DeleteMapping("/{id}")
    public Result<String> delete(@PathVariable Integer id) {
        usersInfoService.removeById(id);
        return Result.success().msg("删除成功");
    }

    /**
     * 批量删除接口
     * @param ids
     * @return
     */
    @ApiOperationSupport(author = "Mr.Abel")
    @ApiOperation(value = "批量删除接口")
    @PostMapping("/del/batch")
    public Result<String> deleteBatch(@RequestBody List<Integer> ids) {
        usersInfoService.removeByIds(ids);
        return Result.success().msg("批量删除成功");
    }
}